# -*- coding: utf-8 -*-
"""
@Time    : 2024/9/13 14:53 
@Author  : ZhangShenao 
@File    : 2.__slots__魔法.py 
@Desc    : __slots__魔法

Python是一门动态语言,允许在运行时为对象动态绑定属性和方法
当然也可以对已经绑定的属性和方法进行解绑定

如果我们需要限定自定义类型的对象只能绑定某些属性
可以通过在类中定义__slots__变量来进行限定
__slots__是一个类变量,可以用来声明一个类实例应该拥有的属性
__slots__ 的主要作用是限制实例的属性,并且可以节省内存
需要注意的是:__slots__的限定只对当前类的对象生效,对子类并不起任何作用

关于__slots__的关键点:
1. 内存优化: 通常,Python对象的属性存储在一个字典中,这会占用较多的内存
            通过使用 __slots__,可以告诉Python不要为每个实例使用字典,而是为固定的属性集分配空间
            这样可以显著减少每个实例的内存占用,特别是当有大量实例时
2. 属性限制: 使用 __slots__ 可以限制类的实例能够拥有的属性
            这意味着,一旦定义了 __slots__,实例就不能有不在 __slots__ 中定义的属性
3. 类型限制: 你可以为 __slots__ 中的每个属性指定一个类型,
            这可以通过使用slot类型注解来完成
"""

from person import Person

if __name__ == '__main__':
    # 创建Person对象
    p = Person(name="Tom", age=6)

    # Python是一门动态语言,允许在运行时为对象动态绑定属性和方法
    # 当然也可以对已经绑定的属性和方法进行解绑定
    p._gender = "男"
    print(p._gender)

    # 因为Person对象已经通过__slots__限定了只能绑定_name、_age和_gender属性
    # 因此_eat属性无法绑定
    # p._eat = lambda: print("吃猫粮")
    # p._eat()  # 'Person' object has no attribute '_eat'
